package service_manager

import (
	pb "ReferenceMonitor/sdk/rpc/pb_gen"
	"context"
	"fmt"
	"google.golang.org/grpc"
	"time"
)

type ClientRPC struct {
	conn   *grpc.ClientConn
	client pb.DeviceAuthenticationClient
	curDev *DeviceInfo
}

func NewClientRPC(ip string, curDev *DeviceInfo) *ClientRPC {
	addr := fmt.Sprintf("%s:%d", ip, SERVICE_PORT)
	conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithBlock())
	if err != nil {
		fmt.Println("Connect failed", err)
		return nil
	}
	client := pb.NewDeviceAuthenticationClient(conn)
	return &ClientRPC{
		conn:   conn,
		client: client,
		curDev: curDev,
	}
}

func (c *ClientRPC) FindDevice() (DeviceInfo, error) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	req := pb.Request{Cmd: "find_device", Msg: c.curDev.Tag}
	res, err := c.client.FindDevice(ctx, &req)
	if err != nil {
		fmt.Println("[Client] Failed to call RPC FindDevice")
		return DeviceInfo{}, err
	}
	dev := DeviceInfo{
		Name:   res.Name,
		Tag:    res.Tag,
		DType:  res.Type,
		Status: STATUS_UNVERIFY,
	}
	fmt.Println("FindDevice: ", res.Tag)
	return dev, nil
}

func (c *ClientRPC) VerifyDevice(code string) (bool, string) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	fmt.Println("Try to Register Dev: ", c.curDev.Tag, code)
	dev := pb.DeviceInfo{
		Name: c.curDev.Name,
		Type: c.curDev.DType,
		Tag:  c.curDev.Tag,
	}
	msg := pb.DeviceVerifyMsg{Msg: code, Info: &dev}
	res, err := c.client.RegisterDevice(ctx, &msg)
	if err != nil {
		fmt.Println("[Client] Failed to call RPC RegisterDevice", err)
		return false, ""
	}
	fmt.Println("Success to Register to Devices: ", dev.Tag)
	return res.Ok, res.Msg
}
